package net.csdn.business.gateway.component;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.StaticScriptSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Auther: zhangyalei
 * @Date: 2022/12/22 16:33
 * @Description:
 */
@Component
public class HourRateLimitRedisLua {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * @Desc:
     * @Author: zhangyalei
     * @param KEYS[1]: 命名空间+uid或者ip的hash;ARGV[1]: 过期时间; ARGV[2]：初始化数据
     * @Date: 2022/12/22 18:14
     */
    public static final String SUBTRACTS_LUA = new StringBuilder()
            .append("   if (redis.call('exists', KEYS[1]) >0 ) then " +
                    "   local remain = tonumber(redis.call('get', KEYS[1])); " +
                    "   local flag= 0" +
                    "   if(remain > 0) then " +
                    "       remain=redis.call('incrby', KEYS[1],  -1); " +
                    "       flag=1" +
                    "   end; " +
                    "   local time= tonumber(redis.call('ttl', KEYS[1])); " +
                    "   return string.format('{\"remain\":%d, \"time\":%d, \"flag\":%d}', remain, time,flag);   " +
                    "   end;    ")
            .append("   if (redis.call('exists', KEYS[1]) == 0 ) then  " +
                    "       redis.call('set', KEYS[1], ARGV[2]); " +
                    "       redis.call('expire', KEYS[1], ARGV[1]); " +
                    "       local remain = tonumber(redis.call('incrby', KEYS[1], -1)); " +
                    "       local time=tonumber(redis.call('ttl', KEYS[1])); " +
                    "       return string.format('{\"remain\":%d, \"time\":%d, \"flag\":%d}', remain, time,1);  " +
                    "   end; ").toString();

            /*.append("if (redis.call('exists', KEYS[1]) == 1 and redis.call('exists', KEYS[2]) == 1) then")
            .append("    local temp1 = tonumber(redis.call('get', KEYS[1]));")
            .append("    local temp2 = tonumber(redis.call('get', KEYS[2]));")
            .append("    local num = tonumber(ARGV[1]);")
            .append("    local temp = temp1 + temp2;")
            .append("    if (temp >= num) then")
            .append("        if (temp1 >= num) then")
            .append("            redis.call('incrby', KEYS[1], 0 - num);")
            .append("           return string.format('{\"'..KEYS[1]..'\":%d}', num);")
            .append("        else")
            .append("            redis.call('set', KEYS[1], 0);")
            .append("            local num = (num - temp1);")
            .append("            redis.call('incrby', KEYS[2], 0 - num);")
            .append("            return string.format('{\"'..KEYS[1]..'\":%d, \"'..KEYS[2]..'\":%d}', temp1, num);")
            .append("        end;")
            .append("    end;")
            .append("    return '-2';")
            .append("end;")
            .append("return '-1';").toString();*/

    /**
     * @Desc: 
     * @Author: zhangyalei
     * @param key1: 命名空间+uid或者ip的hash;ARGV[1]: 过期时间; ARGV[2]：初始化数据
     * @Date: 2022/12/22 18:14
     */

    public JSONObject subtracts(String key1,Integer arg1, Integer arg2) {
        JSONObject result =null;
        String resultStr = subtractsDo(key1, arg1, arg2);
        // 初始化
        if (StringUtils.isNotBlank(resultStr)) {
            result= JSON.parseObject(resultStr);

        }
        return result;
    }

    private String subtractsDo(String key1,Integer arg1, Integer arg2) {
        DefaultRedisScript<String> defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setResultType(String.class);
        defaultRedisScript.setScriptSource(new StaticScriptSource(SUBTRACTS_LUA));
        return redisTemplate.execute(defaultRedisScript, redisTemplate.getValueSerializer(), redisTemplate.getStringSerializer(),
                Lists.newArrayList(key1), arg1,arg2);
    }

}
